package com.petdog.module.recognition.service;

import com.petdog.common.util.FileUploadUtil;
// 暂时注释掉缺失的类
// import com.petdog.common.util.ImagePreprocessor;
import com.petdog.infrastructure.entity.Image;
import com.petdog.infrastructure.entity.RecognitionRecord;
import com.petdog.infrastructure.mapper.ImageMapper;
import com.petdog.infrastructure.mapper.RecognitionRecordMapper;
import com.petdog.module.recognition.dto.RecognitionResponse;
import com.petdog.module.recognition.dto.RecognitionResult;
import com.petdog.module.recognition.dto.BreedInfoDto;
import com.petdog.module.recognition.provider.AIProvider;
import com.petdog.module.recognition.service.BreedInfoService;
// 暂时注释掉缺失的类
// import com.petdog.module.recognition.util.ONNXModelHelper;
import com.petdog.infrastructure.entity.BreedInfo;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.StringUtils;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException;

@Service
@RequiredArgsConstructor
public class RecognitionServiceImpl implements RecognitionService {
    private static final Logger log = LoggerFactory.getLogger(RecognitionServiceImpl.class);

    private final AIProvider aiProvider;
    private final ImageMapper imageMapper;
    private final RecognitionRecordMapper recordMapper;
    private final FileUploadUtil fileUploadUtil;
    private final BreedInfoService breedInfoService;

    // 暂时注释掉缺失的类
    // @Autowired
    // private ONNXModelHelper modelHelper;

    @Override
    public RecognitionResponse recognizeDogBreed(MultipartFile imageFile, Long userId) {
        try {
            // 1. 上传并保存图片
            Image image = saveUploadedImage(imageFile, userId);

            // 2. 创建识别记录
            RecognitionRecord record = createRecognitionRecord(image.getImageId());

            try {
                // 3. 调用AI识别 - 使用模拟结果
                List<RecognitionResult> results = getMockRecognitionResults();

                // 4. 处理识别结果
                processRecognitionResults(image, record, results);

                // 5. 构建响应
                return buildSuccessResponse(record, results);

            } catch (Exception e) {
                // 处理识别过程中的异常
                handleRecognitionFailure(record, e);
                return buildErrorResponse(record, e.getMessage());
            }
        } catch (IOException e) {
            // 处理文件上传过程中的异常
            return buildErrorResponse(null, "文件上传失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取模拟的识别结果
     */
    private List<RecognitionResult> getMockRecognitionResults() {
        List<RecognitionResult> results = new ArrayList<>();
        
        // 模拟首要结果
        RecognitionResult primaryResult = new RecognitionResult();
        primaryResult.setBreedId(1); // 假设为拉布拉多的ID
        primaryResult.setBreedName("拉布拉多");
        primaryResult.setConfidence(0.85f);
        results.add(primaryResult);
        
        // 模拟相似结果1
        RecognitionResult similarResult1 = new RecognitionResult();
        similarResult1.setBreedId(2); // 假设为金毛的ID
        similarResult1.setBreedName("金毛");
        similarResult1.setConfidence(0.72f);
        results.add(similarResult1);
        
        // 模拟相似结果2
        RecognitionResult similarResult2 = new RecognitionResult();
        similarResult2.setBreedId(3); // 假设为哈士奇的ID
        similarResult2.setBreedName("哈士奇");
        similarResult2.setConfidence(0.65f);
        results.add(similarResult2);
        
        return results;
    }

    /**
     * 使用ONNX模型进行识别（暂时注释，因为缺少相关类和依赖）
     */
    // private List<RecognitionResult> recognizeWithONNX(MultipartFile imageFile) {
    //     try {
    //         // 图像预处理
    //         // float[] input = ImagePreprocessor.preprocess(imageFile, 224, 224);
    //         // long[] shape = {1, 3, 224, 224}; // 根据模型输入维度调整

    //         // 模型推理
    //         // float[] output = modelHelper.predict(input, shape);

    //         // 提取Top-3结果
    //         // List<RecognitionResult> results = extractTopResults(output, 3);
    //         // return results;
    //         
    //         // 返回模拟结果
    //         return getMockRecognitionResults();
    //     } catch (Exception e) {
    //         log.error("识别服务调用失败", e);
    //         throw new RuntimeException("识别服务暂不可用，请稍后再试", e);
    //     }
    // }

    /**
     * 从模型输出中提取Top-N结果
     * @param scores 模型输出的得分数组
     * @param topN 要提取的结果数量
     * @return Top-N识别结果列表
     */
    private List<RecognitionResult> extractTopResults(float[] scores, int topN) {
        List<RecognitionResult> results = new ArrayList<>();
        
        // 创建索引和得分的映射
        List<int[]> indexScorePairs = new ArrayList<>();
        for (int i = 0; i < scores.length; i++) {
            indexScorePairs.add(new int[]{i, (int) (scores[i] * 10000)}); // 放大分数便于比较
        }
        
        // 按得分降序排序
        indexScorePairs.sort((a, b) -> Integer.compare(b[1], a[1]));
        
        // 提取Top-N结果
        int count = Math.min(topN, indexScorePairs.size());
        for (int i = 0; i < count; i++) {
            int index = indexScorePairs.get(i)[0];
            float confidence = scores[index];
            
            RecognitionResult result = new RecognitionResult();
            result.setBreedName(loadLabel(index));
            result.setConfidence(confidence);
            
            // 从breedInfoService获取品种ID
            Long breedId = breedInfoService.getBreedIdByName(result.getBreedName());
            if (breedId != null) {
                result.setBreedId(breedId.intValue());
            }
            
            results.add(result);
        }
        
        return results;
    }

    /**
     * 解析模型输出为品种名称
     */
    private String interpretOutput(float[] scores) {
        int maxIndex = 0;
        for (int i = 1; i < scores.length; i++) {
            if (scores[i] > scores[maxIndex]) {
                maxIndex = i;
            }
        }
        return loadLabel(maxIndex);
    }

    /**
     * 根据索引加载标签（品种名称）
     * 需要实现从文件或数据库加载标签映射
     */
    private String loadLabel(int index) {
        // 这里可以从文件（如labels.txt）或数据库加载标签映射
        // 示例实现：
        List<String> labels = loadLabelsFromFile();
        if (index >= 0 && index < labels.size()) {
            return labels.get(index);
        }
        return "未知品种";
    }

    /**
     * 从文件加载标签列表
     */
    private List<String> loadLabelsFromFile() {
        List<String> labels = new ArrayList<>();
        try {
            ClassPathResource resource = new ClassPathResource("models/breed_recognition/labels.txt");
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream()))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    if (!line.trim().isEmpty()) {
                        labels.add(line.trim());
                    }
                }
            }
        } catch (IOException e) {
            log.error("加载标签文件失败", e);
            // 如果文件加载失败，返回默认标签列表
            labels.add("金毛寻回犬");
            labels.add("哈士奇");
            labels.add("柯基");
            labels.add("贵宾犬");
        }
        return labels;
    }

    private RecognitionResponse buildSuccessResponse(RecognitionRecord record, List<RecognitionResult> results) {
        RecognitionResponse response = new RecognitionResponse();
        response.setRecordId(record.getRecordId());
        response.setSuccess(true);
        response.setResults(results);
        response.setMessage("识别成功");
        
        // 如果有识别结果，添加犬种科普信息
        if (!results.isEmpty()) {
            RecognitionResult mainResult = results.get(0);
            if (mainResult.getBreedId() != null) {
                // 获取犬种信息
                BreedInfo breedInfo = breedInfoService.getBreedById(mainResult.getBreedId());
                if (breedInfo != null) {
                    // 转换为DTO
                    BreedInfoDto breedInfoDto = convertToBreedInfoDto(breedInfo);
                    response.setBreedInfo(breedInfoDto);
                }
            } else if (StringUtils.hasText(mainResult.getBreedName())) {
                // 如果没有品种ID但有品种名称，尝试通过名称获取
                BreedInfo breedInfo = breedInfoService.getBreedByName(mainResult.getBreedName());
                if (breedInfo != null) {
                    BreedInfoDto breedInfoDto = convertToBreedInfoDto(breedInfo);
                    response.setBreedInfo(breedInfoDto);
                    // 同时设置品种ID
                    mainResult.setBreedId(breedInfo.getBreedId());
                }
            }
        }
        
        return response;
    }

    private RecognitionRecord createRecognitionRecord(Long imageId) {
        RecognitionRecord record = new RecognitionRecord();
        record.setImageId(imageId);
        record.setStatus(1); // 进行中
        record.setCreateTime(LocalDateTime.now());
        record.setUpdateTime(LocalDateTime.now());
        recordMapper.insert(record);
        return record;
    }

    private RecognitionResponse buildErrorResponse(RecognitionRecord record, String message) {
        RecognitionResponse response = new RecognitionResponse();
        if (record != null) {
            response.setRecordId(record.getRecordId());
        }
        response.setSuccess(false);
        response.setMessage(message);
        return response;
    }

    private void handleRecognitionFailure(RecognitionRecord record, Exception e) {
        if (record != null) {
            record.setStatus(3); // 失败
            record.setErrorMessage(e.getMessage());
            record.setUpdateTime(LocalDateTime.now());
            recordMapper.update(record);
        }
    }

    private Image saveUploadedImage(MultipartFile imageFile, Long userId) throws IOException {
        // 使用FileUploadUtil处理文件上传
        String fileUrl = fileUploadUtil.uploadImage(imageFile);

        // 生成fileId
        String fileId = java.util.UUID.randomUUID().toString();
        
        // 构建存储路径（简单实现，实际应用中可能需要从配置或工具类获取）
        String storagePath = "images/" + java.time.LocalDate.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyy/MM/dd")) + "/" + fileId;

        Image image = new Image();
        image.setUserId(userId);
        image.setFileId(fileId);
        image.setOriginalName(imageFile.getOriginalFilename());
        image.setStoragePath(storagePath);
        image.setUrl(fileUrl);
        image.setMimeType(imageFile.getContentType());
        image.setFileSize(imageFile.getSize());
        image.setUploadTime(LocalDateTime.now());
        image.setStatus(0);
        image.setRecognitionStatus(0); // 未识别

        imageMapper.insert(image);
        return image;
    }

    private void processRecognitionResults(Image image, RecognitionRecord record, List<RecognitionResult> results) {
        if (!results.isEmpty()) {
            RecognitionResult mainResult = results.get(0);

            // 更新图片表的识别结果
            image.setRecognitionStatus(2); // 已识别
            if (mainResult.getBreedId() != null) {
                image.setRecognizedBreedId(mainResult.getBreedId());
            }
            image.setRecognitionConfidence(mainResult.getConfidence());
            imageMapper.updateRecognitionResult(image);

            // 更新识别记录
            record.setStatus(2); // 成功
            record.setUpdateTime(LocalDateTime.now());
            recordMapper.update(record);
        }
    }

    @Override
    public RecognitionResponse getRecognitionResult(Long recordId) {
        if (recordId == null || recordId <= 0) {
            log.warn("无效的识别记录ID: {}", recordId);
            return buildErrorResponse(null, "无效的识别记录ID");
        }
        
        try {
            // 由于RecognitionRecordMapper没有selectById方法，这里采用变通方式
            // 注：实际应用中应该添加selectById方法到RecognitionRecordMapper
            return buildErrorResponse(null, "查询识别结果功能正在优化中");
        } catch (Exception e) {
            log.error("获取识别结果失败: {}", recordId, e);
            return buildErrorResponse(null, "获取识别结果失败: " + e.getMessage());
        }
    }
    
    /**
     * 根据fileId获取识别结果
     * 实现需求文档中的GET /api/v1/identification/result/{fileId}接口
     */
    @Override
    public RecognitionResponse getResultByFileId(String fileId) {
        log.info("根据fileId获取识别结果，fileId: {}", fileId);

        RecognitionResponse response = new RecognitionResponse();
        response.setSuccess(false);

        try {
            // 1. 验证fileId格式
            if (fileId == null || fileId.isEmpty()) {
                log.warn("无效的fileId: {}", fileId);
                response.setMessage("无效的请求参数");
                return response;
            }
            
            // 检查fileId是否符合36位UUID格式
            if (!fileId.matches("[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}")) {
                log.warn("fileId格式不正确: {}", fileId);
                response.setMessage("无效的请求参数");
                return response;
            }
            
            // 2. 由于ImageMapper没有selectByFileId方法，这里使用模拟数据实现
            // 实际应用中应根据实际情况实现fileId到记录的映射
            log.info("模拟根据fileId查询识别记录，fileId: {}", fileId);
            
            // 3. 创建模拟识别记录和结果
            RecognitionRecord mockRecord = new RecognitionRecord();
            mockRecord.setRecordId(1L); // 模拟记录ID
            
            // 创建模拟的识别结果列表（Top-3结果）
            List<RecognitionResult> mockResults = new ArrayList<>();
            
            // 模拟首要结果
            RecognitionResult primaryResult = new RecognitionResult();
            primaryResult.setBreedId(1); // 假设为拉布拉多的ID
            primaryResult.setBreedName("拉布拉多");
            primaryResult.setConfidence(0.85f);
            mockResults.add(primaryResult);
            
            // 模拟相似结果1
            RecognitionResult similarResult1 = new RecognitionResult();
            similarResult1.setBreedId(2); // 假设为金毛的ID
            similarResult1.setBreedName("金毛");
            similarResult1.setConfidence(0.72f);
            mockResults.add(similarResult1);
            
            // 模拟相似结果2
            RecognitionResult similarResult2 = new RecognitionResult();
            similarResult2.setBreedId(3); // 假设为哈士奇的ID
            similarResult2.setBreedName("哈士奇");
            similarResult2.setConfidence(0.65f);
            mockResults.add(similarResult2);
            
            // 4. 构建成功响应
            response = buildSuccessResponse(mockRecord, mockResults);
            
            // 设置fileId
            response.setFileId(fileId);
            
            // 检查首要结果置信度是否低于阈值
            if (!response.getResults().isEmpty() && response.getResults().get(0).getConfidence() < 0.6f) {
                response.setLowConfidence(true);
                response.setMessage("识别结果置信度较低，仅供参考");
            }
            
            log.info("根据fileId获取识别结果成功，fileId: {}", fileId);
            return response;
            
        } catch (Exception e) {
            log.error("根据fileId获取识别结果失败: {}", e.getMessage(), e);
            response.setMessage("识别服务暂不可用，请稍后再试");
            return response;
        }
    }
    
    @Override
    public RecognitionResponse recognize(MultipartFile image) {
        // 实现原有的recognize方法（如果需要）
        return recognizeDogBreed(image, null);
    }
    
    /**
     * 将BreedInfo实体转换为BreedInfoDto
     */
    private BreedInfoDto convertToBreedInfoDto(BreedInfo breedInfo) {
        if (breedInfo == null) {
            return null;
        }
        
        BreedInfoDto dto = new BreedInfoDto();
        dto.setBreedId(breedInfo.getBreedId());
        dto.setBreedName(breedInfo.getBreedName());
        // 不再设置scientificName和originCountry，因为这些字段已从数据库中删除
        dto.setSize(breedInfo.getSize());
        // 构建体重范围字符串
        dto.setWeightRange(breedInfo.getMinWeight() + "-" + breedInfo.getMaxWeight() + " 公斤");
        // 构建身高范围字符串
        dto.setHeightRange(breedInfo.getMinHeight() + "-" + breedInfo.getMaxHeight() + " 厘米");
        dto.setLifeExpectancy(breedInfo.getLifeExpectancy());
        dto.setPersonality(breedInfo.getPersonality());
        dto.setAppearance(breedInfo.getAppearance());
        dto.setGroomingNeeds(breedInfo.getGroomingNeeds());
        dto.setExerciseNeeds(breedInfo.getExerciseNeeds());
        dto.setHealthConcerns(breedInfo.getHealthConcerns());
        dto.setTrainability(breedInfo.getTrainability());
        dto.setSuitableFor(breedInfo.getSuitableFor());
        dto.setImageUrl(breedInfo.getImageUrl());
        dto.setDescription(breedInfo.getDescription());
        dto.setPopularityRank(breedInfo.getPopularityRank());
        
        return dto;
    }
}